
/***************************************************************************** \
 *                Test some Utility-funcitons
\*****************************************************************************/

/*! @file
 *
 *  @brief
 *    Test some functions in ColUtil
 *
 *  Type './utils -h' for an explanation of the command line options.
 *
 *
 *  The different tests are:
 *    - sign-function
 *    - Coplanarity
 *    - Colinearity
 *    - AxistoMat-function
 *    - geomFromPoints- and makeCube-functions
 *
 * Warning: Due to problems writing to stdout in windows,
 *          there is no axistoMat-test in that version
 *
 *  @author Rene Weller 
 *	- reimplemented by Weiyu Yi, wyi@tu-clausthal.de
 *
 **/


//---------------------------------------------------------------------------
//  Includes
//---------------------------------------------------------------------------

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <limits.h>

#if defined(__APPLE__)
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif

#include <ColIntersect.h>
#include <ColDefs.h>
#include <ColUtils.h>
#include <ColExceptions.h>

#include <ColUtilsOpenGL.h>

#ifdef _WIN32
#ifdef max
#undef max
#endif
#ifdef min
#undef min
#endif
#endif

using col::ColGeometry;
using col::Vector3;
using col::Primitive;
using col::Point3;

/***************************************************************************\
 *                        Global variables                                 *
\***************************************************************************/

namespace {

const int Num_rand_triangles = 1000;

} // namespace



/***************************************************************************\
 *                        Test cases                                       *
\***************************************************************************/

// Write the Vertices and Faces to outfile in VRML-Style
void writeGeom( const ColGeometry * geo, FILE *outfile )
{
    if( geo == NULL )
        return;

    //Write Points:
    for( unsigned int i = 0; i < geo->getPointsPtr()->size(); i++ )
    {
		REAL p0 = geo->getPointsPtr()->at(i)[0];
		REAL p1 = geo->getPointsPtr()->at(i)[1];
		REAL p2 = geo->getPointsPtr()->at(i)[2];
        fprintf( outfile, "%f %f %f", p0, p1, p2 );
        //fprintf( outfile, "%f %f %f", geo->getPointsPtr()->at(i)[0], geo->getPointsPtr()->at(i)[1], geo->getPointsPtr()->at(i)[2] );

        if( i == geo->getPointsPtr()->size() - 1 )
        {
            fprintf( outfile, "\n");
        }
        else
        {
            fprintf( outfile, ", \n");
        }
    }

    //Write Faces
    for( unsigned int i=0; i < geo->getPrimitivesPtr()->size(); i++ )
    {
        for(unsigned int j = 0; j < geo->getPrimitivesPtr()->at(i).size(); j++ )
        {
            fprintf( outfile, "%d, ", geo->getPrimitivesPtr()->at(i)[j] );
        }   
        fprintf(outfile, "\n");
    }
}


void testcase( int *phase )
{
	int result_wanted;
	int result = 0;
    REAL test;

    Vector3 v1, v2;

	printf("phase %d\n", *phase );
	switch ( *phase )
	{
		//test sign
		case 0:
            test = 0.0;
            if ( !col::sign ( test ) )
                result++;
            else printf( "Error in sign-test 1\n" );

            test = -1.0;
            if ( col::sign ( test ) )
                result++;
            else printf( "Error in sign-test 2\n" );

            test = 1.0;
            if ( !col::sign ( test ) )
                result++;
            else printf( "Error in sign-test 3\n" );

            test = FLT_MAX;
            if ( !col::sign ( test ) )
                result++;
            else printf( "Error in sign-test 4\n" );

            test = -FLT_MAX;
            if ( col::sign ( test ) )
                result++;
            else printf( "Error in sign-test 5\n" );

			result_wanted = 5;
			(*phase) ++ ;
			break;

        //test colinear
		case 1:
			// 2 vectors		
			v1[0] = 0;  v1[1] = 1;  v1[2] = 0;
			v2[0] = 1;  v2[1] = 0;  v2[2] = 0;        
            if (! col::collinear( v1, v2 ) )
                result ++;
            else printf( "Error in colinearity-test\n" );

			// 2 identic vectors
			v1[0] = 0;  v1[1] = 1;  v1[2] = 0;
			v2[0] = 0;  v2[1] = 1;  v2[2] = 0;
            if ( col::collinear( v1, v2 ) )
                result ++;
            else printf( "Error in colinearity-test\n" );
            
			// 2 colinear vectors	
			v1[0] = 0;  v1[1] = 1;  v1[2] = 0;
            v2[0] = 0;  v2[1] = ( 1 / col::NearZero ) - 1.0 ;  v2[2] = 0;     
            if ( col::collinear( v1, v2 ) )
                result ++;
            else printf( "Error in colinearity-test\n" );
            
			//vector 1 = 0			
			v1[0] = 0;  v1[1] = 0;  v1[2] = 0;
			v2[0] = 1;  v2[1] = 0;  v2[2] = 0;
            if ( !col::collinear ( v1, v2 ) )
                result ++;
            else printf( "Error in colinearity-test\n" );
            
			//both vectors = 0		
			v1[0] = 0;  v1[1] = 0;  v1[2] = 0;
			v2[0] = 0;  v2[1] = 0;  v2[2] = 0;
            if ( !col::collinear ( v1, v2 ) )
                result ++;
            else printf( "Error in colinearity-test\n" );

			(*phase) ++ ;
			result_wanted = 5;
			break;

        case 2:
		{
			ColGeometry * geo = new ColGeometry();
			col::makeCube( geo, 1 );

            writeGeom( geo, stdout );
            (*phase) ++ ;
			result_wanted = -1;
			break;
		}
		default:
			// last phase has been reached, signal to caller
			*phase = 0;
	}

	if ( *phase > 0 )  // skip default: case
	{
		if ( result_wanted != -1 )
		{
			printf( (result != result_wanted ) ? "ERROR!\n" : " -> OK\n" );
		}
	}
}




/***************************************************************************\
 *                              Main                                       *
\***************************************************************************/

int main( int argc, char *argv[] )
{
	int phase = 0;
	do
		testcase( &phase );
	while ( phase > 0 );

	return 0;
}


char cvsid[] =
"@(#)$Id: intersect.cpp,v 1.6 2004/02/26 14:50:40 ehlgen Exp $";



/**  Zum Abpasten fuer eine Funktion, Methode, oder Makro-"Funktion".
 *
 * @param param1	Comment for param1
 *
 * @return
 *   Text for return value.
 *
 * Detaillierte Beschreibung ...
 *
 * @throw Exception
 *  Beschreibung ..
 *
 * @warning
 *   Dinge, die der Aufrufer unbedingt beachten muss...
 *
 * @assumptions
 *   Annahmnen, die die Funktion macht...
 *
 * @sideeffects
 *   Nebenwirkungen, globale Variablen, die veraendert werden, ..
 *
 * @todo
 *   Was noch getan werden muss
 *
 * @bug
 *   Bekannte Bugs dieser Funktion
 *
 * @see
 *   ...
 *
 * @internal
 *   Implementierungsdetails, TODOs, ...
 *
 **/

